package world.square;

import java.util.List;

/**
 * Interfaces for squares which support teleportation to a different square.
 * 
 * @invar 	Each possible destination must be valid.
 *          | for each destination in getDestinations():
 *          |    isValidDestination(destination) 
 *          
 * @author Frederic Mes, Wim Marynissen
 * @version 1.0
 */
public interface Teleportation{
	/**
	 * Return the destinations of this teleporation square.
	 * @return	A list of possible destinations.
	 */
	public abstract List<Square> getDestinations();
    
    /**
     * Add a number of destinations to the teleportation square.
     * @param	destinations
     * 			The destinations to be added.
     * @pre		The destinations must be valid.
     * 			| for each destination in destinations:
     * 			| 	isValidDestination(destination)
     * @effect	Each destination is added to this teleportation square.
     * 			| for each destination in destinations
     * 			| 	addDestination(destination)
     */
	public abstract void addDestinations(List<Square> destinations);
	
	/**
     * Add a destination to the teleportation square.
     * @param	destination
     * 			The destination to be added.
     * @pre		The destination must be valid.
     * 			| isValidDestination(destination)
     * @return	The new destination is added to the destination list.
     * 			| result == (new this).getdestinations().contains(destination)
     */
	public abstract boolean addDestination(Square destination);
    
    /**
     * Remove some of the destination squares.
     * @param 	destinations
     * 			The destinations to be removed.
     * @pre		The destinations must be valid.
     * 			| for each destination in destinations:
     * 			| 	canRemoveDestination(destination)
     * @effect	Each specified destination is removed from this teleportation square.
     * 			| for each destination in destinations
     * 			| 	removeDestination(destination)
     */
	public abstract void removeDestinations(List<Square> destinations);
	
	/**
     * Remove a destination to the teleportation square.
     * @param	destination
     * 			The destination to be removed.
     * @pre		The destination must be valid.
     * 			| canRemoveDestination(destination)
     * @return	The specified destination is removed from the destination list.
     * 			| 	result == !(new this).getdestinations().contains(destination)
     */
	public abstract boolean removeDestination(Square destination);
    
	/**
     * Check if the square can be used as destination for teleportation.
     * @param 	square
     * 			The square to be evaluated for removal.
     * @return	The square must be effective, not a rock and not equal to this square.
     * 			| if(square == null)
     * 			|	 then result == false
     * @return	The square must be in the list of destinations.
     * 			| 	result == getdestinations().contains(destination)
     */
	public abstract boolean canRemoveDestination(Square square);
	
    /**
     * Check if the square can be used as destination for teleportation.
     * @param 	square
     * 			The square to validate.
     * @return	The square must be effective, not a rock and not equal to this square.
     * 			| result == ((square != null)
     * 			| 				&& !(square instanceof Rock) 
     * 			|					&& !(square.equals(this)))
     */
	public abstract boolean isValidDestination(Square square);
    
    
    /**
     * Get a random destination.
     * @return	A destination from the possible destinations.
     * 			| getDestinations().contains(result)
     */
	public abstract Square randomDestination();
    
    /**
     * Check if the specified square is a destination of this teleportation square.
     * @param 	destination
     * 			The destination to look for.
     * @return	True if the specified square is in the list of possible destinations.
     * 			| result == getDestinations().contains(destination)
     */
	public abstract boolean hasDestination(Square destination);

}
